//
//  DiaryController.swift
//  
//
//  Created by Jiang Chencheng on 2024/9/12.
//

import Vapor
import Fluent

struct DiaryController: RouteCollection {
    func boot(routes: any Vapor.RoutesBuilder) throws {
        
        let diary = routes
            .grouped("diary")
            .grouped(SessionToken.authenticator(), SessionToken.guardMiddleware())
        
        // write a diary
        diary.post("write", use: writeDiary)
        // query diary list
        diary.get("list", use: queryDiaryList)
        // delete a photo with id
        diary.post("delete", use: deleteDiary)
    }
}

extension DiaryController {
    
    @Sendable
    func writeDiary(req: Request) async throws -> BizResponse<RewardResp> {
        
        let userID = try req.getAuthedUserID()
        
        let body = try req.content.decode(WriteDiaryReq.self)
        
        let myRoom = try await Room.query(on: req.db, userID: userID)
        
        let diary = Diary(content: body.content)
        
        try await req.db.transaction {
            try await myRoom.$diaries.create(diary, on: $0)
            myRoom.star += 20
            try await myRoom.save(on: $0)
            try await Event.log(on: $0, roomID: myRoom.requireID(), userID: userID, action: .writeDiary, comment: "write diary reward 20 stars")
        }
        
        let reward = RewardResp.Reward(value: 20, type: .star)
        let resp = RewardResp(reward: reward, room: myRoom.toDTO())
        return BizResponse(data: resp)
    }
    
    @Sendable
    func queryDiaryList(req: Request) async throws -> BizResponse<Page<DiaryDTO>> {
        
        let userID = try req.getAuthedUserID()
        let myRoom = try await Room.query(on: req.db, userID: userID)
        
        let result = try await myRoom.$diaries
            .query(on: req.db)
            .paginate(for: req)
        
        let page = result.map {
            $0.toDTO()
        }
        
        return BizResponse(data: page)
    }
    
    @Sendable
    func deleteDiary(req: Request) async throws -> BizResponse<BizVoid> {
  
        let userID = try req.getAuthedUserID()
        
        let body = try req.content.decode(DeleteDiaryReq.self)
        
        let myRoom = try await Room.query(on: req.db, userID: userID)
        
        try await req.db.transaction {
            try await myRoom.$diaries.query(on: $0)
                .filter(\.$id == body.id)
                .delete()
            try await Event.log(on: $0, roomID: myRoom.requireID(), userID: userID, action: .deleteDiary)
        }
        
        return BizResponse()
    }
}
